﻿using KinonekoSoftware.CodariaDB.Documents.Index;
using KinonekoSoftware.CodariaDB.Documents.Relationships.Characters;
using KinonekoSoftware.CodariaDB.Documents.Relationships.Country;

namespace KinonekoSoftware.CodariaDB.Documents.Relationships
{
    public sealed class RelationEngine : Engine
    {
        #region Character

        public void AddRelation(CharacterRelationship relationship)
        {
            if (relationship is null)
            {
                return;
            }

            CharacterDB.Insert(relationship);
        }

        public void UpdateRelation(CharacterRelationship relationship)
        {

            if (relationship is null)
            {
                return;
            }

            CharacterDB.Update(relationship);
        }

        public void RemoveRelation(CharacterRelationship relationship)
        {
            if (relationship is null)
            {
                return;
            }

            CharacterDB.Delete(relationship.Id);
        }



        public void RemoveRelationships(InstanceCache target)
        {
            if (target is null)
            {
                return;
            }

            //
            //
            var set = GetCharacterRelationship(target.Id).Select(x => x.Id)
                                                         .ToHashSet();

            //
            //
            CharacterDB.DeleteMany(x => set.Contains(x.Id));
        }

        public void RemoveCharacterRelationships(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return;
            }

            //
            //
            var set = GetCharacterRelationship(id).Select(x => x.Id)
                                                  .ToHashSet();

            //
            //
            CharacterDB.DeleteMany(x => set.Contains(x.Id));
        }

        public IEnumerable<CharacterRelationship> GetCharacterRelationship(string id)
        {
            return CharacterDB.Find(x => x.SourceID == id ||
                                         x.TargetID == id);
        }


        public IEnumerable<CharacterRelationship> GetCharacterRelationships()
        {
            return CharacterDB.FindAll();
        }

        #endregion


        #region Country

        public void AddRelation(CountryRelationship relationship)
        {
            if (relationship is null)
            {
                return;
            }

            CountryDB.Insert(relationship);
        }

        public void UpdateRelation(CountryRelationship relationship)
        {

            if (relationship is null)
            {
                return;
            }

            CountryDB.Update(relationship);
        }

        public void RemoveRelation(CountryRelationship relationship)
        {
            if (relationship is null)
            {
                return;
            }

            CountryDB.Delete(relationship.Id);
        }



        public void RemoveCountryRelations(InstanceCache target)
        {
            if (target is null)
            {
                return;
            }

            //
            //
            var set = GetCountryRelations(target.Id).Select(x => x.Id)
                                                    .ToHashSet();

            //
            //
            CountryDB.DeleteMany(x => set.Contains(x.Id));
        }

        public void RemoveCountryRelations(string id)
        {
            if (string.IsNullOrEmpty(id))
            {
                return;
            }

            //
            //
            var set = GetCountryRelations(id).Select(x => x.Id)
                                             .ToHashSet();

            //
            //
            CountryDB.DeleteMany(x => set.Contains(x.Id));
        }

        public IEnumerable<CountryRelationship> GetCountryRelations(string id)
        {
            return CountryDB.Find(x => x.SourceID == id ||
                                       x.TargetID == id);
        }


        public IEnumerable<CountryRelationship> GetCountryRelations()
        {
            return CountryDB.FindAll();
        }

        #endregion

        protected override void OnDatabaseOpening(RepositoryOpenContext context)
        {
            var repo = context.Repository;
            CharacterDB = repo.Get<CharacterRelationship>(CollectionNames.Relationship_Character);
            CountryDB   = repo.Get<CountryRelationship>(CollectionNames.Relationship_Character);
        }

        protected override void OnDatabaseClosing(ILogger logger)
        {
            CharacterDB = null;
            CountryDB   = null;
        }


        public ILiteCollection<CharacterRelationship> CharacterDB { get; private set; }
        public ILiteCollection<CountryRelationship>   CountryDB   { get; private set; }

        public override string EngineID => EngineNames.Relationship;
    }
}